package com.huaqiang.tools.verificationcode;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.List;
import java.util.Random;

/**
 * @Author: 张强
 * @Date: 2025/3/20 10:57
 */
@Component
public class VerificationCode {

    /**
     * @auther: 张强
     * @date: 2025/3/20 11:00
     * @description: 生成验证码图片的宽度
     */
    @Value("${com.huaqiang.tools.verificationcode.width:100}")
    private int width;

    /**
     * @auther: 张强
     * @date: 2025/3/20 11:01
     * @description: 生成验证码图片的高度
     */
    @Value("${com.huaqiang.tools.verificationcode.height:30}")
    private int height;

    /**
     * @auther: 张强
     * @date: 2025/3/20 11:09
     * @description: 背景颜色rgb
     */
    @Value("${com.huaqiang.tools.verificationcode.bgColorRgb:255.255.255}")
    private String bgColorRgb;

    /**
     * @auther: 张强
     * @date: 2025/3/20 11:01
     * @description:
     */
    private String[] fontNames = {"宋体", "楷体", "隶书", "微软雅黑"};
    /**
     * @auther: 张强
     * @date: 2025/3/20 11:01
     * @description: 定义验证码图片的背景颜色为白色
     */
    private Color bgColor = new Color(255, 255, 255);


    private Random random = new Random();

    /**
     * @auther: 张强
     * @date: 2025/3/20 11:12
     * @description: 验证码源
     */
    @Value("${com.huaqiang.tools.verificationcode.codesOrigin:23456789abcdefghjklmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ}")
    private String codesOrigin;
    /**
     * @auther: 张强
     * @date: 2025/3/20 11:01
     * @description: 记录随机字符串
     */
    private String verificationCode;

    public int getWidth() {
        return width;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public String getBgColorRgb() {
        return bgColorRgb;
    }

    public void setBgColorRgb(String bgColorRgb) {
        this.bgColorRgb = bgColorRgb;
    }

    public String getCodesOrigin() {
        return codesOrigin;
    }

    public void setCodesOrigin(String codesOrigin) {
        this.codesOrigin = codesOrigin;
    }

    /**
     * 获取一个随意颜色
     *
     * @return
     */
    private Color randomColor() {
        int red = random.nextInt(150);
        int green = random.nextInt(150);
        int blue = random.nextInt(150);
        return new Color(red, green, blue);
    }

    /**
     * 获取一个随机字体
     *
     * @return
     */
    private Font randomFont() {
        String name = fontNames[random.nextInt(fontNames.length)];
        int style = random.nextInt(4);
        int size = random.nextInt(5) + 24;
        return new Font(name, style, size);
    }

    /**
     * 获取一个随机字符
     *
     * @return
     */
    private char randomChar() {
        return codesOrigin.charAt(random.nextInt(codesOrigin.length()));
    }

    /**
     * 创建一个空白的BufferedImage对象
     *
     * @return
     */
    private BufferedImage createImage() {
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = (Graphics2D) image.getGraphics();
        // 设置验证码图片的背景颜色f
        if (null != bgColorRgb && "" != bgColorRgb) {
            List<String> bgColorRgbList = Arrays.asList(bgColorRgb.split(","));
            bgColor = new Color(Integer.parseInt(bgColorRgbList.get(0)),
                    Integer.parseInt(bgColorRgbList.get(1)), Integer.parseInt(bgColorRgbList.get(2)));
        }
        g2.setColor(bgColor);
        g2.fillRect(0, 0, width, height);
        return image;
    }

    public BufferedImage getImage() {
        BufferedImage image = createImage();
        Graphics2D g2 = (Graphics2D) image.getGraphics();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < 4; i++) {
            String s = randomChar() + "";
            sb.append(s);
            g2.setColor(randomColor());
            g2.setFont(randomFont());
            float x = i * width * 1.0f / 4;
            g2.drawString(s, x, height - 8);
        }
        this.verificationCode = sb.toString();
        drawLine(image);
        return image;
    }

    /**
     * 绘制干扰线
     *
     * @param image
     */
    private void drawLine(BufferedImage image) {
        Graphics2D g2 = (Graphics2D) image.getGraphics();
        int num = 5;
        for (int i = 0; i < num; i++) {
            int x1 = random.nextInt(width);
            int y1 = random.nextInt(height);
            int x2 = random.nextInt(width);
            int y2 = random.nextInt(height);
            g2.setColor(randomColor());
            g2.setStroke(new BasicStroke(1.5f));
            g2.drawLine(x1, y1, x2, y2);
        }
    }

    public String getVerificationCode() {
        return verificationCode;
    }

    public void output(BufferedImage image, OutputStream out) throws IOException {
        ImageIO.write(image, "JPEG", out);
    }
}
